package com.libui.utils

import android.annotation.SuppressLint
import android.app.Activity
import android.app.Dialog
import android.content.ClipData
import android.content.Context
import android.content.ContextWrapper
import android.content.Intent
import android.net.Uri
import android.provider.MediaStore
import android.view.LayoutInflater
import android.widget.TextView
import androidx.core.content.FileProvider
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.libbase.utils.FileUtils
import com.libui.BaseActivity
import com.libui.R
import com.libui.permissions.PermissionCallback
import com.libui.permissions.Permissions
import com.tencent.smtt.sdk.ValueCallback
import com.tencent.smtt.sdk.WebChromeClient
import java.io.File
import java.util.*

class FileChooserUtils {
    companion object {
        const val REQUEST_CODE_FILE_CHOOSER = 0xFF01
        const val REQUEST_CODE_CAMERA = 0xFF02

        val instance: FileChooserUtils by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
            FileChooserUtils()
        }
    }

    private var filePathCallback: ValueCallback<Array<Uri>>? = null

    private var fileChooserDialog: Dialog? = null

    private var cameraImageUri: Uri? = null

    fun chooseFile(
        context: Context,
        filePathCallback: ValueCallback<Array<Uri>>,
        fileChooserParams: WebChromeClient.FileChooserParams
    ) {
        if (this.filePathCallback != null) {
            this.filePathCallback?.onReceiveValue(null)
        }
        this.filePathCallback = filePathCallback

        showFileChooserDialog(context, fileChooserParams)
    }

    private fun showFileChooserDialog(
        context: Context,
        fileChooserParams: WebChromeClient.FileChooserParams
    ) {
        val activity = context as? BaseActivity
        if (activity == null) {
            filePathCallback?.onReceiveValue(null)
            return
        }

        val dialog = BottomSheetDialog(context, R.style.FileChooserDialog)
        dialog.setOnDismissListener {
            filePathCallback?.onReceiveValue(null)
            filePathCallback = null

            fileChooserDialog = null
            cameraImageUri = null
        }

        @SuppressLint("InflateParams")
        val view = LayoutInflater.from(context).inflate(R.layout.file_chooser_dialog, null, false)

        // 相册
        val album = view.findViewById<TextView>(R.id.pickPhotoBtn)
        album.setOnClickListener {
            val intent = fileChooserParams.createIntent()
            intent.putExtra(
                Intent.EXTRA_ALLOW_MULTIPLE,
                fileChooserParams.mode == WebChromeClient.FileChooserParams.MODE_OPEN_MULTIPLE
            )
            activity.startActivityForResult(intent, REQUEST_CODE_FILE_CHOOSER)
        }

        // 相机
        val camera = view.findViewById<TextView>(R.id.takePhotoBtn)
        camera.setOnClickListener {
            Permissions(context)
                .requestCameraPermission(object : PermissionCallback {
                    override fun onGranted(permissions: List<String>, allGranted: Boolean) {
                        val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
                        val imageUri =
                            FileProvider.getUriForFile(
                                context,
                                "${context.packageName}.libui.fileprovider",
                                File(
                                    FileUtils.instance.getCacheDir(ContextWrapper(context)),
                                    "${Date().time}.jpg"
                                )
                            ).also { cameraImageUri = it }

                        intent.putExtra(
                            MediaStore.EXTRA_OUTPUT,
                            imageUri
                        )
                        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
                        activity.startActivityForResult(intent, REQUEST_CODE_CAMERA)
                    }

                    override fun onDenied(permissions: List<String>, doNotAskAgain: Boolean) {
                    }
                })
        }

        // 取消
        val cancel = view.findViewById<TextView>(R.id.cancelBtn)
        cancel.setOnClickListener {
            dialog.dismiss()
        }

        dialog.setContentView(view)
        dialog.show()

        fileChooserDialog = dialog
    }

    fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?): Boolean {
        return when (requestCode) {
            REQUEST_CODE_FILE_CHOOSER -> {
                if (resultCode == Activity.RESULT_OK) {
                    val clipData: ClipData? = data?.clipData

                    val uris: Array<Uri>? = if (clipData != null) {
                        val items = mutableListOf<Uri>()
                        for (i in 0 until clipData.itemCount) {
                            items.add(clipData.getItemAt(i).uri)
                        }
                        if (items.isNotEmpty()) {
                            items.toTypedArray()
                        } else {
                            null
                        }
                    } else {
                        WebChromeClient.FileChooserParams.parseResult(resultCode, data)
                    }

                    filePathCallback?.onReceiveValue(uris)
                } else {
                    filePathCallback?.onReceiveValue(null)
                }

                filePathCallback = null
                fileChooserDialog?.dismiss()

                true
            }

            REQUEST_CODE_CAMERA -> {
                cameraImageUri?.let {
                    if (resultCode == Activity.RESULT_OK) {
                        filePathCallback?.onReceiveValue(arrayOf(it))
                        cameraImageUri = null
                    } else {
                        filePathCallback?.onReceiveValue(null)
                    }

                } ?: filePathCallback?.onReceiveValue(null)

                filePathCallback = null
                fileChooserDialog?.dismiss()

                true
            }

            else -> {
                false
            }
        }
    }
}